#ifndef EMS_DEVICE_DEVICE_BASE_H
#define EMS_DEVICE_DEVICE_BASE_H

#include "protocol/ProtocolInterface.h"
#include "protocol/modbus/ProtocolManager.h"
#include "utils/Json.h"

#include <string>
#include <memory>
#include <vector>
#include <map>
#include <atomic>
#include <mutex>

namespace ems {
namespace device {

enum class DeviceStatus {
    DISCONNECTED,
    CONNECTING,
    CONNECTED,
    ERROR,
    MAINTENANCE
};

struct DataValue {
    std::string key;
    double value;
    std::string unit;
    uint64_t timestamp;
    bool valid;
    std::string deviceCategory;  // 设备类别 (pcs/bms/alarm)

    DataValue() : value(0.0), timestamp(0), valid(false) {}
    DataValue(const std::string& k, double v, const std::string& u, uint64_t t = 0, const std::string& dc = "")
        : key(k), value(v), unit(u), timestamp(t), valid(true), deviceCategory(dc) {}
};

class DeviceBase {
public:
    DeviceBase(const std::string& id, const std::string& name, const std::string& type);
    virtual ~DeviceBase();
    
    virtual bool initialize() = 0;
    virtual bool connect() = 0;
    virtual void disconnect() = 0;
    virtual bool isConnected() const = 0;
    
    virtual bool collectData(std::vector<DataValue>& data) = 0;
    virtual bool writeData(const std::string& key, double value) = 0;
    
    const std::string& getId() const { return id_; }
    const std::string& getName() const { return name_; }
    const std::string& getType() const { return type_; }
    
    DeviceStatus getStatus() const { return status_; }
    std::string getStatusString() const;
    
    uint64_t getLastCollectionTime() const { return lastCollectionTime_; }
    uint64_t getLastErrorTime() const { return lastErrorTime_; }
    std::string getLastError() const;
    
    void setEnabled(bool enabled) { enabled_ = enabled; }
    bool isEnabled() const { return enabled_; }
    
    void setPollInterval(int intervalMs) { pollInterval_ = intervalMs; }
    int getPollInterval() const { return pollInterval_; }

protected:
    void setStatus(DeviceStatus status);
    void setLastError(const std::string& error);
    uint64_t getCurrentTimestamp() const;
    
    std::string id_;
    std::string name_;
    std::string type_;
    
    std::atomic<DeviceStatus> status_;
    std::atomic<bool> enabled_;
    std::atomic<int> pollInterval_;
    std::atomic<uint64_t> lastCollectionTime_;
    std::atomic<uint64_t> lastErrorTime_;
    
    mutable std::mutex errorMutex_;
    std::string lastError_;
    
    std::unique_ptr<protocol::ProtocolInterface> protocol_;
    std::unique_ptr<protocol::ProtocolManager> protocolManager_;
};

}  // namespace device
}  // namespace ems

#endif  // EMS_DEVICE_DEVICE_BASE_H